使用Github Actions自动打包Go项目
前言
如果用过 Gitlab Ci, 相信对此也非常熟悉,GitHub Actions 是 GitHub 推出的持续集成(Continuous Integration,简称 CI)服务,它提供了整套虚拟服务器环境,基于它可以进行构建、测试、打包、部署项目等等操作
快速开始(Quickstart)
点击 Configure, 此时会生成一个 .github/workflow/go.yml 文件
1# This workflow will build a golang project 2# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 4name: Go 5 6on: 7 push: 8 branches: [ "master" ] 9 pull_request: 10 branches: [ "master" ] 11 12jobs: 13 14 build: 15 runs-on: ubuntu-latest 16 steps: 17 - uses: actions/checkout@v3 18 - name: Set up Go 19 uses: actions/setup-go@v3 20 with: 21 go-version: 1.19 22 - name: Build 23 run: go build -v ./... 24 - name: Test 25 run: go test -v ./...
多平台编译(Cross Compile)
交叉编译
对于非 CGO 项目,Go 提供了一种十分方便的方式来进行交叉编译,只需要指定 GOOS 和 GOARCH 环境变量
-
Mac下编译Linux, Windows平台的64位可执行程序:
1$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build . 2$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build .
-
Linux下编译Mac, Windows平台的64位可执行程序:
1$ CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build . 2$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build .
同样的,我们可以在 Gtihub Actions 中设置环境变量来编译非 CGO 项目,这里需要使用 matrix 策略,让我们基于不同的参数创建并行的任务,比如编译Go时指定不同的环境变量
-
首先编写任务
1jobs: 2 build: 3 strategy: 4 matrix: 5 goos: [linux, darwin] 6 goarch: [amd64] 7 8 runs-on: ubuntu-latest 9 10 steps: 11 - name: Checkout 12 uses: actions/checkout@v3 13 - name: Set up Go 14 uses: actions/setup-go@v3 15 with: 16 go-version: 1.19 17 - name: Download dependencies 18 run: go mod download 19 - name: Build 20 run: go build -v -o snow . 21 # 指定编译时的环境变量 22 env: 23 GOOS: ${{ matrix.goos }} 24 GOARCH: ${{ matrix.goarch }} 25 CGO_ENABLED: 0
这样就创建了
GOOS=linux GOARCH=amd64和GOOS=darwin GOARCH=amd64的两个任务, 当goarch增加一个arm的参数后,会组合成四个任务, 如果需要指定或者排除某个选项,可以使用include或者exclude1matrix: 2 goos: [linux, darwin] 3 goarch: [amd64, arm] 4 # 只包括linux编译选项 5 include: 6 - goos: linux 7 goarch: amd64 8 - goos: linux 9 goarch: arm 10 # 排除所有关于arm的编译选项 11 exclude: 12 - goarch: arm
-
然后执行
git push, 这样就能在Github的Actions标签页看到执行结果
跨平台编译
如果是非 CGO 项目,可以使用Go内置的交叉编译,但如果是 CGO 项目,上述的交叉编译大概率会失败(相关问题:go-libsass), 所以我们需要基于不同的平台来进行编译,幸运的是,Github Actions 对此支持的非常好,
-
编写新任务
1jobs: 2 build: 3 strategy: 4 matrix: 5 build: [macos, linux] 6 include: 7 - build: macos 8 os: macos-latest 9 - build: linux 10 os: ubuntu-18.04 11 runs-on: ${{ matrix.os }} 12 steps: 13 - name: Checkout 14 uses: actions/checkout@v3 15 - name: Set up Go 16 uses: actions/setup-go@v3 17 with: 18 go-version: 1.19 19 - name: Download dependencies 20 run: go mod download 21 - name: Build 22 run: go build -v -o snow . 23 env: 24 CGO_ENABLED: 1
注意
runs-on使用的matrix.os变量, 它允许我们分别使用ubuntu-18.04和macos-latest两个平台进行编译,这时不用指定GOOS和GOARCH参数
发布(Release)
当编译好一个二进制文件后,需要发布到 Github 的 Release 页,这时就需要添加新的任务, 目前官方的actions/create-release已经无人维护,所以此次选择另外一个ncipollo/release-action
1name: Release 2 3on: 4 # 只在预发布时才执行 5 release: 6 types: [prereleased] 7 8jobs: 9 build: 10 strategy: 11 matrix: 12 build: [macos, linux] 13 include: 14 - build: macos 15 os: macos-latest 16 archive-name: darwin.tar.gz 17 - build: linux 18 os: ubuntu-latest 19 archive-name: linux.tar.gz 20 21 # 需要设置写权限才能自动发布 22 permissions: 23 contents: write 24 25 steps: 26 ... 27 # 把二进制文件打包成压缩文件 28 - name: Prepare Packaging 29 run: tar zcvf snow-${{ matrix.archive-name }}.tar.gz snow LICENSE 30 31 # 上传附件 32 - name: Upload Artifacts 33 uses: actions/upload-artifact@v3 34 with: 35 name: snow-${{ matrix.archive-name }}.tar.gz 36 path: snow-${{ matrix.archive-name }}.tar.gz 37 38 # 发布release版本 39 - name: Release version 40 uses: ncipollo/release-action@v1 41 if: github.event_name == 'release' 42 with: 43 allowUpdates: true 44 artifacts: snow-${{ matrix.archive-name }}.tar.gz 45 token: ${{ secrets.GITHUB_TOKEN }}
当 Github Actions 执行完成后,就能在 Release 页看到我们发布的 Package
FAQ
version `GLIBC_2.33' not found
使用 Github Actions 发布一个新的版本,下载到本地执行时报错
1./snow: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by ./snow) 2./snow: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./snow) 3./snow: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./snow) 4./snow: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./snow)
这是由于使用的 ubuntu 版本太高导致, 降低版本即可
1include: 2... 3- os: ubuntu-latest 4+ os: ubuntu-18.04
Bad CPU type in executable
这是由于最新的 macos-latest 仅包括arm64,不再包括x86_64导致,如果需要使用x86_64,请指定版本 macos-13
